// Copyright 2016 The StudyGolang Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// http://studygolang.com
// Author: polaris	polaris@homeland.com

package main

import (
	"github.com/polaris1119/keyword"
	"io/ioutil"
	"math/rand"
	"os"
	"path/filepath"
	"strconv"
	"time"

	"github.com/mootdx/homeland/app/global"
	"github.com/mootdx/homeland/app/http/controller"
	"github.com/mootdx/homeland/app/http/controller/admin"
	"github.com/mootdx/homeland/app/http/controller/app"
	pwm "github.com/mootdx/homeland/app/http/middleware"
	"github.com/mootdx/homeland/app/logic"
	thirdmw "github.com/mootdx/homeland/app/middleware"

	"github.com/fatih/structs"
	"github.com/labstack/echo/v4"
	mw "github.com/labstack/echo/v4/middleware"
	. "github.com/polaris1119/config"
	"github.com/polaris1119/logger"
)

func init() {
	// 设置随机数种子
	rand.Seed(time.Now().Unix())
	structs.DefaultTagName = "json"
}

func main() {

	// 支持根据参数打印版本信息
	global.PrintVersion(os.Stdout)

	// 生成保存 pid
	savePid()

	global.App.Init(logic.WebsiteSetting.Domain)

	logger.Init(ROOT+"/runtime/log", ConfigFile.MustValue("global", "log_level", "DEBUG"))

	go keyword.Extractor.Init(keyword.DefaultProps, true, ROOT+"/config/keywords/programming.txt,"+ROOT+"/config/keywords/dictionary.txt")

	go logic.Book.ClearRedisUser()

	// go pprof
	Pprof(ConfigFile.MustValue("global", "pprof", "127.0.0.1:8096"))

	// 初始化 echo 框架
	e := echo.New()

	// 静态文件
	serveStatic(e)

	//日志等各种中间件
	e.Use(thirdmw.EchoLogger())

	// Recover returns a middleware which recovers from panics anywhere in the chain
	// and handles the control to the centralized HTTPErrorHandler.
	e.Use(mw.Recover())

	//Installed 用于 echo 框架，判断是否已经安装了
	e.Use(pwm.Installed(filterPrefixs))

	//HTTPError 用于 echo 框架的 HTTP 错误
	e.Use(pwm.HTTPError())

	// AutoLogin 用于 echo 框架的自动登录和通过 cookie 获取用户信息
	e.Use(pwm.AutoLogin())

	// 评论后不会立马显示出来，暂时缓存去掉
	// frontG := e.Group("", thirdmw.EchoCache())
	// 前端路由组
	frontG := e.Group("")
	controller.RegisterRoutes(frontG)

	// 后台路由组
	adminG := e.Group("/admin", pwm.NeedLogin(), pwm.AdminAuth())
	admin.RegisterRoutes(adminG)

	// app 路由组
	// appG := e.Group("/app", thirdmw.EchoCache())
	appG := e.Group("/app")
	app.RegisterRoutes(appG)

	// 读取配置IP
	e.Server.Addr = getAddr()

	// 运行服务器,
	gracefulRun(e.Server)
}

func getAddr() string {
	host := ConfigFile.MustValue("listen", "host", "")

	if host == "" {
		global.App.Host = "localhost"
	} else {
		global.App.Host = host
	}

	global.App.Port = ConfigFile.MustValue("listen", "port", "8088")

	return host + ":" + global.App.Port
}

func savePid() {
	pidFilename := ROOT + "/runtime/pid/" + filepath.Base(os.Args[0]) + ".pid"
	pid := os.Getpid()

	err := ioutil.WriteFile(pidFilename, []byte(strconv.Itoa(pid)), 0755)
	if err != nil {
		return
	}
}
